
class myPromise {
    /*
    创建实例时：
    定义resolve和reject方法
    执行传入的回调函数
     */
    constructor(fn) {
        //? 定义状态
        this.status = 'pending'
        //? 定义值
        this.value = ''
        //? 定义存储成功和失败的回调函数的数组
        this.resolveArr = []
        this.rejectArr = []
        //? 定义resolve方法
        this.resolve = (value) => {
            //? 执行resolve Promise的状态将由pending转为fulfilled
            if (this.status === 'pending') {
                this.status = 'fulfilled'
                //? 值等于resolve函数的参数
                this.value = value
                //? 因为resolve函数执行后，将会触发回调函数的执行，且resolve的参数将会作为回调函数的参数
                this.resolveArr.forEach((callback) => {
                    callback(this.value)
                })
            }
        }
        //? 定义reject方法 跟resolve方法类似
        this.reject = (reason) => {
            if (this.status === 'pending') {
                this.status = 'rejected'
                this.value = reason
                this.rejectArr.forEach((callback) =>{
                    callback(this.value)
                })
            }
        }
        //? 执行执行器(执行传入的回调函数)
        try {
            //? fn函数的两个参数就是resolve函数和reject函数
            fn(this.resolve,this.reject)
        }catch (e) {
            this.reject(e)
        }
    }
    /*
     ? then方法 其参数当然是成功时执行的回调函数和失败时执行的回调函数
     ? 调用then时需要返回一个新的Promise，
     */
    then(onFulfilled, onRejected) {
        //? then方法需要return一个新的Promise
        //? fulfilled状态 需要执行resolve了
        //? 牢记new Promise 的两个参数:resolve函数和reject函数
        //? 这里是需要处理没有传入onfulfilled和onRejected的情况！
        onFulfilled =
            typeof onFulfilled === "function" ? onFulfilled : (value) => value;
        onRejected =
            typeof onRejected === "function"
                ? onRejected
                : (err) => {
                    throw err;
                };
        //? 返回新的 Promise 对象 这里传resolve reject 是自己身上在构造器中新建的
        return new myPromise((resolve, reject) => {
            //? 这里需要根据状态行事 fulfilled和rejected需要立即执行 pending状态则添加成功和失败的回调函数
            // **这里为什么能够用this.status来判断状态？因为this是指向上一个Promise的(因为谁调用this就指向谁，所以这个this是指向上一个Promise的，很巧妙这里)**
            if (this.status === 'fulfilled') {
                try {
                    //? 需要判断这个回调函数结果还是不是Promise
                    //? 如果返回的是一个 Promise 对象，则等待 Promise 对象解决
                    //? 当然是使用上一个resolve的value
                    const x = onFulfilled(this.value)

                    if (x instanceof myPromise) {
                        x.then(resolve, reject)
                    } else {
                        //? 这一步的操作 是将这个新Promise置为成功
                        resolve(x)
                    }
                } catch (e) {
                    //? 如果执行 onFulfilled 函数抛出异常，则直接拒绝新 Promise 对象
                    reject(e);
                }
            }
            if (this.status === 'rejected') {
                try {
                    const x = onRejected(this.value)
                    if (x instanceof myPromise) {
                        x.then(resolve, reject)
                    } else {
                        //* 返回的新的promise是fulfilled
                        resolve(x)
                    }
                } catch (e) {
                    reject(e)
                }
            }
            //? 如果状态为 pending，则保存成功和失败的回调函数，需要等待状态更新后执行(then必然要等待前面的结果出来才执行)
            // * 这里放入了数组，那么什么时候执行呢？此时构造函数中的回调函数仍未执行完成，状态未改变.但当回调函数执行完成，resolve方法被调用，数组中的函数也被拿出来执行了！
            // * 更深层次的解释是 Promise.then是微任务，当前面是宏任务时，then会先于宏任务执行，此时状态为pending 所以需要存进去。当执行到前面的任务时，取出执行回调函数
            if (this.status === 'pending') {
                //? 这里使用value 因为resolve执行时会把value赋给this.value
                this.resolveArr.push((value) => {
                    try {
                        const x = onFulfilled(value);
                        if (x instanceof myPromise) {
                            x.then(resolve, reject);
                        } else {
                            resolve(x);
                        }
                    } catch (e) {
                        reject(e)
                    }
                })
                this.rejectArr.push((reason) => {
                    try {
                        const x = onRejected(reason);
                        if (x instanceof myPromise) {
                            x.then(resolve, reject);
                        } else {
                            resolve(x);
                        }
                    } catch (e) {
                        reject(e);
                    }
                });
            }
        });
    }
    catch(onRejected) {
        return this.then(null, onRejected);
    }
}
/*
? 执行：
? 1.执行构造函数，构造函数将执行此回调函数 此回调函数里有resolve 即可将状态设为成功
? 2.再执行.then() 传入两个函数作为参数.进入then方法后，将会新创建一个Promise 再执行回调函数 then里新建的Promise里的回调函数是
 */

// new myPromise((resolve,reject) => {
//     setTimeout(()=>{
//         reject('1')
//     },1000)
// }).then((resolve,reject) => {
//     console.log('solve',resolve)
// }).catch(err => console.log('err',err))
// // console.log(mp);
new myPromise((resolve,reject) => {resolve()}).then(()=>{
    console.log(1)
}).catch(() => {
    console.log(2)
}).then(() => {
    console.log(3)
})

new myPromise((resolve,reject) => {resolve()}).then(()=>{
    console.log(1)
    throw new Error('1')
}).catch(() => {
    console.log(2)
}).then(() => {
    console.log(3)
})
